package com.java.cg.seckill.task;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.java.cg.seckill.dao.SeckillGoodsDao;
import com.java.cg.seckill.entity.SeckillGoods;
import com.java.cg.seckill.entity.SeckillOrder;
import com.java.cg.seckill.entity.SeckillStatus;
import com.java.common.constants.CacheKey;
import com.java.common.exception.RRException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 多线程下单
 */
@Component
public class MultiThreadingCreateOrder {
	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private SeckillGoodsDao seckillGoodsDao;

	//异步创建订单
	@Async
	public void createrOrder() {
		//从队列中获取抢单信息()
		SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps(CacheKey.SEC_KILL_USER_QUEUE_KEY).rightPop();

		if (seckillStatus != null) {
			//测试使用写死
			String time = seckillStatus.getTime();
			Long id = seckillStatus.getGoodsId();//秒杀商品的ID
			String username = seckillStatus.getUsername();

			//判断 先从队列中获取商品 ,如果能获取到,说明 有库存,如果获取不到,说明 没库存 卖完了 return.

			Object o = redisTemplate.boundListOps(CacheKey.SEC_KILL_CHAOMAI_LIST_KEY_PREFIX + id).rightPop();
			if (o == null) {
				//卖完了
				//清除 掉  防止重复排队的key
				redisTemplate.boundHashOps(CacheKey.SEC_KILL_QUEUE_REPEAT_KEY).delete(username);
				//清除 掉  排队标识(存储用户的抢单信息)
				redisTemplate.boundHashOps(CacheKey.SEC_KILL_USER_STATUS_KEY).delete(username);
				return;
			}

			//1.根据商品的ID 获取秒杀商品的数据
			SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(CacheKey.SEC_KILL_GOODS_PREFIX + time).get(id);
			//2.判断是否有库存  如果 没有  抛出异常 :卖完了
			if (seckillGoods == null || seckillGoods.getStockCount() <= 0) {
				throw new RRException("商品已售罄!!");
			}

			//3.创建秒杀订单
			SeckillOrder seckillOrder = new SeckillOrder();
			seckillOrder.setId(IdWorker.getId());//订单的ID
			seckillOrder.setSeckillId(id);//秒杀商品ID
			seckillOrder.setMoney(seckillGoods.getCostPrice());//金额
			seckillOrder.setUserId(username);//登录的用户名
			seckillOrder.setCreateTime(new Date());//创建时间
			seckillOrder.setStatus("0");//未支付
			/**
			 * 秒杀订单存入redis,一个用户只允许有一个为支付的秒杀订单
			 */
			redisTemplate.boundHashOps(CacheKey.SEC_KILL_ORDER_KEY).put(username, seckillOrder);

			//4.减redis库存
			seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);

			//5.判断库存是是否为0  如果 是,更新到数据库中,删除掉redis中的秒杀商品
			Long size = redisTemplate.boundListOps(CacheKey.SEC_KILL_CHAOMAI_LIST_KEY_PREFIX + id).size();
			if (size <= 0) {
				//同步库存到mysql
				seckillGoodsDao.updateById(seckillGoods);//数据库的库存更新为0
				redisTemplate.boundHashOps(CacheKey.SEC_KILL_GOODS_PREFIX + time).delete(id);
			} else {
				//设置回redis中
				redisTemplate.boundHashOps(CacheKey.SEC_KILL_GOODS_PREFIX + time).put(id, seckillGoods);

			}
			//6.创建订单成功()
			try {
				System.out.println("开始模拟下单操作=====start====" + new Date() + Thread.currentThread().getName());
				Thread.sleep(10000);
				System.out.println("开始模拟下单操作=====end====" + new Date() + Thread.currentThread().getName());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			//创建订单成功了 修改用户的抢单的信息
			seckillStatus.setOrderId(seckillOrder.getId());
			seckillStatus.setStatus(2);//
			seckillStatus.setMoney(Float.valueOf(String.valueOf(seckillOrder.getMoney())));
			//重新设置回redis中
			redisTemplate.boundHashOps(CacheKey.SEC_KILL_USER_STATUS_KEY).put(username, seckillStatus);

		}

	}
}
